// CoreFuncs.h

#include "CoreFuncs.h"

CoreFuncs::CoreFuncs(void *rendertarget
		, const CEGUI::String &imageset_rg
		, const CEGUI::String &fonts_rg
		, const CEGUI::String &schemes_rg
		, const CEGUI::String &looknfeels_rg
		, const CEGUI::String &layouts_rg
		, const CEGUI::String &luascripts_rg
		, const CEGUI::String &animations_rg
		, const CEGUI::String &schemas_rg) {
 	// initialise GUI system using the new automagic function
	d_renderer = &CEGUI::OgreRenderer::bootstrapSystem(
			*((Ogre::RenderTarget *)rendertarget)
		);

	// clearing this queue actually makes sure it's created(!)
//	d_renderer->getDefaultRenderingRoot().clearGeometry(CEGUI::RQ_OVERLAY); 

#ifdef _DEBUG
	CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative);
#endif

    // set the default resource groups to be used
	if(imageset_rg.size()>0) {
		CEGUI::Logger::getSingleton().logEvent("Setting imageset def resgrp to " + imageset_rg);
		CEGUI::Imageset::setDefaultResourceGroup(imageset_rg);
	}
    if(fonts_rg.size()>0) CEGUI::Font::setDefaultResourceGroup(fonts_rg);
    if(schemes_rg.size()>0) CEGUI::Scheme::setDefaultResourceGroup(schemes_rg);
    if(looknfeels_rg.size()>0) CEGUI::WidgetLookManager::setDefaultResourceGroup(looknfeels_rg);
    if(layouts_rg.size()>0) CEGUI::WindowManager::setDefaultResourceGroup(layouts_rg);
    if(luascripts_rg.size()>0) CEGUI::ScriptModule::setDefaultResourceGroup(luascripts_rg);
    if(animations_rg.size()>0) CEGUI::AnimationManager::setDefaultResourceGroup(animations_rg);
    
    // setup default group for validation schemas
    CEGUI::XMLParser* parser = CEGUI::System::getSingleton().getXMLParser();
    if (parser->isPropertyPresent("SchemaDefaultResourceGroup"))
        if(schemas_rg.size()>0) parser->setProperty("SchemaDefaultResourceGroup", schemas_rg);
}

CoreFuncs::~CoreFuncs() {

}

void CoreFuncs::createImageSetFromFile(const CEGUI::String &imageset_name, CEGUI::String &filename) {
	CEGUI::ImagesetManager::getSingleton().createFromImageFile(imageset_name, filename);
}

void CoreFuncs::loadImageSet(const CEGUI::String &imagesetfile_name) {
	CEGUI::ImagesetManager::getSingleton().create(imagesetfile_name);
}

void CoreFuncs::loadFont(const CEGUI::String &fontfile_name) {
	CEGUI::FontManager::getSingleton().create(fontfile_name);
}

void CoreFuncs::addListboxTextItemToCB(const CEGUI::String& cbname, const CEGUI::String& text, CEGUI::uint item_id, void* item_data, bool disabled, bool auto_delete) {
	CEGUI::Combobox * cb = static_cast<CEGUI::Combobox*>(
						CEGUI::WindowManager::getSingleton().getWindow(cbname));
	if(cb)
		cb->addItem(new CEGUI::ListboxTextItem(text, item_id, item_data, disabled, auto_delete));
}

void CoreFuncs::timePulse(float timeSinceLastFrame) {
        // always inject a time pulse to enable widget automation
	if(CEGUI::System::getSingletonPtr())
        CEGUI::System::getSingleton().injectTimePulse(timeSinceLastFrame);
}

void CoreFuncs::mouseMoved(const OIS::MouseEvent &e) {
    CEGUI::System *cegui = CEGUI::System::getSingletonPtr();

	if(cegui) {
		cegui->injectMouseMove(e.state.X.rel, e.state.Y.rel);
		cegui->injectMouseWheelChange(e.state.Z.rel / 120.0f);
	}
}

void CoreFuncs::keyPressed(const OIS::KeyEvent &e)
{
    // do event injection
    CEGUI::System *cegui = CEGUI::System::getSingletonPtr();

	if(cegui) {
		// key down
		cegui->injectKeyDown(e.key);
		// now character
	    cegui->injectChar(e.text);
	}
}

void CoreFuncs::keyReleased(const OIS::KeyEvent &e)
{
	CEGUI::System *cegui = CEGUI::System::getSingletonPtr();
	if(cegui)
		cegui->injectKeyUp(e.key); 
}

CEGUI::MouseButton convertOISButtonToCegui(int buttonID) {
	using namespace OIS;

	switch (buttonID)
	{
	case OIS::MB_Left:
		return CEGUI::LeftButton;
	case OIS::MB_Right:
		return CEGUI::RightButton;
	case OIS::MB_Middle:
		return CEGUI::MiddleButton;
	default:
		return CEGUI::LeftButton;
	}
}

void CoreFuncs::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
	CEGUI::System *cegui = CEGUI::System::getSingletonPtr();
	if(cegui)
		cegui->injectMouseButtonDown(convertOISButtonToCegui(id));
}

void CoreFuncs::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
	CEGUI::System *cegui = CEGUI::System::getSingletonPtr();
	if(cegui)
		cegui->injectMouseButtonUp(convertOISButtonToCegui(id));
}

void CoreFuncs::windowResized(float newwidth, float newheight)
{
    CEGUI::System* const sys = CEGUI::System::getSingletonPtr();
    if (sys)
        sys->notifyDisplaySizeChanged(CEGUI::Size(newwidth,newheight));
}

bool CoreFuncs::showMouseCursor(bool s) {
	bool ret = CEGUI::MouseCursor::getSingleton().isVisible();
	CEGUI::MouseCursor::getSingleton().setVisible(s);
	return ret;
}

void CoreFuncs::subscribePushButtonEventClicked(const CEGUI::String &button_name, long id) {
	CEGUI::PushButton * pushButton = static_cast<CEGUI::PushButton*>(
						CEGUI::WindowManager::getSingleton().getWindow(button_name));
	if(pushButton) {
		CEGUI::Logger::getSingleton().logEvent("Registering handler for pushbutton named " 
				+ button_name + ", " + id);
		addHandler(id,*pushButton,CEGUI::PushButton::EventClicked);
	} else {
		CEGUI::Logger::getSingleton().logEvent("No pushbutton named " + button_name + "found!");
	}
}

void CoreFuncs::subscribeListBoxSelectionChanged(const CEGUI::String &listbox_name, long id) {
	CEGUI::Listbox * listbox = static_cast<CEGUI::Listbox*>(
						CEGUI::WindowManager::getSingleton().getWindow(listbox_name));
	if(listbox) {
		addHandler(id,*listbox,CEGUI::Listbox::EventSelectionChanged);
	} else {
		CEGUI::Logger::getSingleton().logEvent("No listbox named " + listbox_name + " found!");
	}
}

void CoreFuncs::subscribeCheckBoxChanged(const CEGUI::String &checkbox_name, long id) {
	CEGUI::Checkbox * checkbox = static_cast<CEGUI::Checkbox*>(
						CEGUI::WindowManager::getSingleton().getWindow(checkbox_name));
	if(checkbox) {
		addHandler(id,*checkbox,CEGUI::Checkbox::EventCheckStateChanged);
	} else {
		CEGUI::Logger::getSingleton().logEvent("No checkbox named " + checkbox_name + " found!");
	}
}

void CoreFuncs::subscribeRadioButtonSelectionChanged(const CEGUI::String &radiobutton_name, long id) {
	CEGUI::RadioButton * radiobutton = static_cast<CEGUI::RadioButton*>(
						CEGUI::WindowManager::getSingleton().getWindow(radiobutton_name));
	if(radiobutton) {
		addHandler(id,*radiobutton,CEGUI::RadioButton::EventSelectStateChanged);
	} else {
		CEGUI::Logger::getSingleton().logEvent("No radiobutton named " + radiobutton_name + " found!");
	}
}

void CoreFuncs::subscribeEditBoxTextAccepted(const CEGUI::String &editbox_name, long id) {
	CEGUI::Editbox  * editbox = static_cast<CEGUI::Editbox *>(
						CEGUI::WindowManager::getSingleton().getWindow(editbox_name));
	if(editbox) {
		addHandler(id,*editbox,CEGUI::Editbox::EventTextAccepted);
	} else {
		CEGUI::Logger::getSingleton().logEvent("No editbox named " + editbox_name + " found!");
	}
}

void CoreFuncs::subscribeWindowCloseClicked(const CEGUI::String &window_name, long id) {
	CEGUI::FrameWindow  * window = static_cast<CEGUI::FrameWindow *>(
						CEGUI::WindowManager::getSingleton().getWindow(window_name));
	if(window) {
		addHandler(id,*window,CEGUI::FrameWindow::EventCloseClicked);
	} else {
		CEGUI::Logger::getSingleton().logEvent("No window named " + window_name + " found!");
	}
}

void CoreFuncs::subscribeMouseClick(const CEGUI::String &widget_name, long id) {
	CEGUI::Window  * window = static_cast<CEGUI::Window *>(
						CEGUI::WindowManager::getSingleton().getWindow(widget_name));
	if(window) {
		addHandler(id,*window,CEGUI::Window::EventMouseClick);
	} else {
		CEGUI::Logger::getSingleton().logEvent("No window named " + widget_name + " found!");
	}
}

